package com.itheima.reggie.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.reggie.dto.DishDto;
import com.itheima.reggie.entity.Category;
import com.itheima.reggie.entity.Dish;
import com.itheima.reggie.entity.DishFlavor;
import com.itheima.reggie.entity.SetmealDish;
import com.itheima.reggie.exception.BusinessException;
import com.itheima.reggie.mapper.CategoryMapper;
import com.itheima.reggie.mapper.DishFlavorMapper;
import com.itheima.reggie.mapper.DishMapper;
import com.itheima.reggie.mapper.SetmealDishMapper;
import com.itheima.reggie.service.DishService;
import com.itheima.reggie.utils.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
@Slf4j
public class DishServiceImpl implements DishService {

    @Resource
    private DishMapper dishMapper;
    @Resource
    private DishFlavorMapper dishFlavorMapper;
    @Resource
    private SetmealDishMapper setmealDishMapper;
    @Resource
    private CategoryMapper categoryMapper;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    @Transactional
    public Result<String> addOneDish(DishDto dishDto) {
        dishMapper.insert(dishDto);
        Long dishId = dishDto.getId();
        List<DishFlavor> flavors = dishDto.getFlavors();
        flavors.stream().map((item) -> {
            item.setDishId(dishId);
            return item;
        }).collect(Collectors.toList());
        for (DishFlavor dishFlavor : flavors) {
            dishFlavorMapper.insert(dishFlavor);
        }
        // 清理redis缓存的属于该菜品分类的数据
        String key = "dish:" + dishDto.getCategoryId() + ":1";
        stringRedisTemplate.delete(key);
        return Result.success("新增菜品成功");
    }

    @Override
    public Result<Page<DishDto>> getPage(String name, int currentPage, int pageSize) {
        LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .like(name != null, Dish::getName, name)
                .orderByDesc(Dish::getUpdateTime);
        Page<Dish> page = new Page<>(currentPage, pageSize);
        dishMapper.selectPage(page, queryWrapper);
        Page<DishDto> dtoPage = new Page<>();
        BeanUtils.copyProperties(page, dtoPage, "records");
        List<Dish> dishList = page.getRecords();
        List<DishDto> dishDtoList = dishList.stream().map((item) -> {
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(item, dishDto);
            Category category = categoryMapper.selectById(item.getCategoryId());
            if (category != null) {
                dishDto.setCategoryName(category.getName());
            }
            return dishDto;
        }).collect(Collectors.toList());
        dtoPage.setRecords(dishDtoList);
        return Result.success(dtoPage);
    }

    @Override
    public Result<DishDto> getDish(Long dishId) {
        Dish dish = dishMapper.selectById(dishId);
        LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DishFlavor::getDishId, dishId);
        List<DishFlavor> dishFlavors = dishFlavorMapper.selectList(queryWrapper);
        DishDto dishDto = new DishDto();
        BeanUtils.copyProperties(dish, dishDto);
        dishDto.setFlavors(dishFlavors);
        return Result.success(dishDto);
    }

    @Override
    public Result<String> updateDish(DishDto dishDto) {
        dishMapper.updateById(dishDto);
        LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DishFlavor::getDishId, dishDto.getId());
        dishFlavorMapper.delete(queryWrapper);
        List<DishFlavor> flavors = dishDto.getFlavors();
        List<DishFlavor> dishFlavorList = flavors.stream().map((item) -> {
            item.setDishId(dishDto.getId());
            return item;
        }).collect(Collectors.toList());
        for (DishFlavor flavor : flavors) {
            dishFlavorMapper.insert(flavor);
        }
        //  清理redis缓存的属于该菜品分类的数据
        String key = "dish:" + dishDto.getCategoryId() + ":1";
        stringRedisTemplate.delete(key);
        return Result.success("菜品修改成功 ");
    }

    /**
     * 根据条件查询菜品
     *
     * @param dish 查询条件
     * @return 菜品列表
     */
    @Override
    public Result<List<DishDto>> getDishList(Dish dish) {
        // 拼接redis的key
        String redisKey = "dish:" + dish.getCategoryId() + ":" + dish.getStatus();
        // 从redis缓存中查询数据
        String dishDtoListJson = stringRedisTemplate.opsForValue().get(redisKey);
        // 如果有则解析后直接返回
        if (StringUtils.isNotEmpty(dishDtoListJson)) {
            List<DishDto> dishDtoList = JSON.parseArray(dishDtoListJson, DishDto.class);
            return Result.success(dishDtoList);
        }
        // 没有则从mysql数据库中查询
        LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .eq(dish.getCategoryId() != null, Dish::getCategoryId, dish.getCategoryId())
                .eq(Dish::getStatus, 1)
                .orderByDesc(Dish::getUpdateTime);
        List<Dish> dishList = dishMapper.selectList(queryWrapper);
        List<DishDto> dishDtoList = dishList.stream().map((item) -> {
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(item, dishDto);
            Long dishId = item.getId();
            LambdaQueryWrapper<DishFlavor> queryWrapper1 = new LambdaQueryWrapper<>();
            queryWrapper1.eq(DishFlavor::getDishId, dishId);
            List<DishFlavor> dishFlavorList = dishFlavorMapper.selectList(queryWrapper1);
            dishDto.setFlavors(dishFlavorList);
            return dishDto;
        }).collect(Collectors.toList());
        // 将结果保存到redis缓存中
        stringRedisTemplate.opsForValue().set(redisKey, JSON.toJSONString(dishDtoList), 30, TimeUnit.MINUTES);
        return Result.success(dishDtoList);
    }

    @Override
    @Transactional
    public Result<String> deleteDishes(List<Long> ids) {
        // 查询所有菜品是否有未停售的
        LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Dish::getId,ids);
        List<Dish> dishList = dishMapper.selectList(queryWrapper);
        for (Dish dish : dishList) {
            // 有未停售的
            if(dish.getStatus()==1){
                // 抛出业务级异常
                throw  new BusinessException("该菜品正在售卖中，不能删除");
            }
        }
        // 要删除的所有菜品中没有未停售的
        // 删除套餐菜品表中该菜品的数据
        LambdaQueryWrapper<SetmealDish> setmealDishQueryWrapper = new LambdaQueryWrapper<>();
        setmealDishQueryWrapper.in(SetmealDish::getDishId,ids);
        setmealDishMapper.delete(setmealDishQueryWrapper);
        // 删除菜品口味表中该菜品的数据
        LambdaQueryWrapper<DishFlavor> dishFlavorQueryWrapper = new LambdaQueryWrapper<>();
        dishFlavorQueryWrapper.in(DishFlavor::getDishId,ids);
        dishFlavorMapper.delete(dishFlavorQueryWrapper);
        // 删除菜品表中该菜品的数据
        LambdaQueryWrapper<Dish> dishQueryWrapper = new LambdaQueryWrapper<>();
        dishQueryWrapper.in(Dish::getId,ids);
        dishMapper.delete(dishQueryWrapper);
        return Result.success("菜品删除成功");
    }

    @Override
    public Result<String> updateDishesStatus(List<Long> ids, int toStatus) {
        LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Dish::getId,ids);
        Dish dish = new Dish();
        dish.setStatus(toStatus);
        dishMapper.update(dish,queryWrapper);
        return Result.success("菜品售卖状态更改成功");
    }
}
